package com.example.oss.config;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.example.oss.core.OssProperties;
import com.example.oss.core.OssTemplate;
import com.example.oss.server.OssTemplateImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * OssAutoConfiguration：自动装配配置类，自动装配的 bean 有 AmazonS3 和 OssTemplate
 * <p>
 * 所使用的注解：
 * 注解 @EnableConfigurationProperties(OssProperties.class)：自动装配我们的配置类 OssProperties
 * 注解 @Bean：声明式 bean
 * 注解 @ConditionalOnMissingBean：修饰 bean 的一个注解，当你的 bean 被注册之后，注册相同类型的 bean，就不会成功，它会保证你的 bean 只有一个
 * 注解 @ConditionalOnBean(AmazonS3.class)：当给定的在 bean 存在时,则实例化当前 Bean。
 */
@Configuration
@EnableConfigurationProperties(OssProperties.class)
public class OssAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public AmazonS3 ossClient(OssProperties ossProperties) {
        // 客户端配置，主要是全局的配置信息
        ClientConfiguration clientConfiguration = new ClientConfiguration();
        // 设置最大连接数
        clientConfiguration.setMaxConnections(ossProperties.getMaxConnections());
        // url以及region配置
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(
                ossProperties.getEndpoint(), ossProperties.getRegion());
        // 凭证配置
        AWSCredentials awsCredentials = new BasicAWSCredentials(ossProperties.getAccessKey(),
                ossProperties.getSecretKey());
        AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
        // 构建Amazon S3客户端的配置
        return AmazonS3Client.builder()
                .withEndpointConfiguration(endpointConfiguration) // 设置终端节点配置，指定服务的URL
                .withClientConfiguration(clientConfiguration) // 设置客户端配置，包括重试、连接超时等设置
                .withCredentials(awsCredentialsProvider) // 设置AWS凭证提供者，用于身份验证
                .disableChunkedEncoding() // 禁用分块编码，可能提高数据传输效率
                .withPathStyleAccessEnabled(ossProperties.getPathStyleAccess()) // 启用路径样式访问，以适应不同的存储桶访问方式
                .build(); // 构建Amazon S3客户端实例
    }

    @Bean
    @ConditionalOnBean(AmazonS3.class)
    public OssTemplate ossTemplate(AmazonS3 amazonS3) {
        return new OssTemplateImpl(amazonS3);
    }

}
